package cn.lngaosu.lwyd.module.integration.service.weixinuser;

import cn.hutool.core.collection.CollUtil;
import cn.lngaosu.lwyd.framework.common.util.http.HttpUtils;
import cn.lngaosu.lwyd.module.infra.service.config.ConfigService;
import cn.lngaosu.lwyd.module.integration.service.apptoken.AppTokenService;
import cn.lngaosu.lwyd.module.integration.service.apptoken.AppTokenServiceImpl;
import cn.lngaosu.lwyd.module.system.dal.dataobject.webinterfacelog.WebinterfaceLogDO;
import cn.lngaosu.lwyd.module.system.dal.mysql.webinterfacelog.WebinterfaceLogMapper;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.concurrent.TimeUnit;

import cn.lngaosu.lwyd.module.integration.controller.admin.weixinuser.vo.*;
import cn.lngaosu.lwyd.module.integration.dal.dataobject.weixinuser.WeixinUserDO;
import cn.lngaosu.lwyd.framework.common.pojo.PageResult;
import cn.lngaosu.lwyd.framework.common.pojo.PageParam;
import cn.lngaosu.lwyd.framework.common.util.object.BeanUtils;

import cn.lngaosu.lwyd.module.integration.dal.mysql.weixinuser.WeixinUserMapper;

import static cn.lngaosu.lwyd.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.lngaosu.lwyd.framework.common.util.collection.CollectionUtils.convertList;
import static cn.lngaosu.lwyd.framework.common.util.collection.CollectionUtils.diffList;
import static cn.lngaosu.lwyd.module.integration.enums.ErrorCodeConstants.*;

/**
 * 微信公众号用户基本信息 Service 实现类
 *
 * @author 张恒
 */
@Service
@Validated
public class WeixinUserServiceImpl implements WeixinUserService {
    private static final Logger logger = LoggerFactory.getLogger(WeixinUserServiceImpl.class);

    @Resource
    private WeixinUserMapper weixinUserMapper;
    @Resource
    private AppTokenService appTokenService;
    @Resource
    private ConfigService configService;
    @Resource
    private WebinterfaceLogMapper webinterfaceLogMapper;

    @Override
    public Long createWeixinUser(WeixinUserSaveReqVO createReqVO) {
        // 插入
        WeixinUserDO weixinUser = BeanUtils.toBean(createReqVO, WeixinUserDO.class);
        weixinUserMapper.insert(weixinUser);
        // 返回
        return weixinUser.getId();
    }

    @Override
    public void updateWeixinUser(WeixinUserSaveReqVO updateReqVO) {
        // 校验存在
        validateWeixinUserExists(updateReqVO.getId());
        // 更新
        WeixinUserDO updateObj = BeanUtils.toBean(updateReqVO, WeixinUserDO.class);
        weixinUserMapper.updateById(updateObj);
    }

    @Override
    public void deleteWeixinUser(Long id) {
        // 校验存在
        validateWeixinUserExists(id);
        // 删除
        weixinUserMapper.deleteById(id);
    }

    @Override
        public void deleteWeixinUserListByIds(List<Long> ids) {
        // 校验存在
        validateWeixinUserExists(ids);
        // 删除
        weixinUserMapper.deleteByIds(ids);
        }

    private void validateWeixinUserExists(List<Long> ids) {
        List<WeixinUserDO> list = weixinUserMapper.selectByIds(ids);
        if (CollUtil.isEmpty(list) || list.size() != ids.size()) {
            throw exception(WEIXIN_USER_NOT_EXISTS);
        }
    }

    private void validateWeixinUserExists(Long id) {
        if (weixinUserMapper.selectById(id) == null) {
            throw exception(WEIXIN_USER_NOT_EXISTS);
        }
    }

    @Override
    public WeixinUserDO getWeixinUser(Long id) {
        return weixinUserMapper.selectById(id);
    }

    @Override
    public PageResult<WeixinUserDO> getWeixinUserPage(WeixinUserPageReqVO pageReqVO) {
        return weixinUserMapper.selectPage(pageReqVO);
    }

    @Override
    public void syncWeixinUser() {
        // 获取微信token
        String weixinToken = appTokenService.getWeixinToken();
        if (StringUtils.isEmpty(weixinToken)) {
            throw exception(WEIXIN_TOKEN_NOT_EXISTS);
        }

        // 接口配置
        String configValue = configService.getConfigValueByKey("weixinConfig");
        if (StringUtils.isEmpty(configValue)) {
            throw exception(INTERFACE_CONFIG_NOT_EXISTS);
        }

        JSONObject configJo = JSONObject.parseObject(configValue);
        // 接口开关
        String onOff = configJo.getString("onOff");
        if (!"on".equals(onOff)) {
            throw exception(INTERFACE_CONFIG_NOT_EXISTS);
        }

        // 获取人员信息列表地址
        String userListUrl = configJo.getString("userListUrl");
        userListUrl = userListUrl + "?access_token=" + weixinToken;
        String next_openid = "";
        // 查询最新的openid
        LambdaQueryWrapper<WeixinUserDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.select(WeixinUserDO::getOpenid).orderByDesc(WeixinUserDO::getId).last(" limit 1 ");
        WeixinUserDO weixinUserDO = weixinUserMapper.selectOne(queryWrapper);
        if (ObjectUtils.isNotEmpty(weixinUserDO)) {
            next_openid = weixinUserDO.getOpenid();
        }

        // 初始化日志数据（默认成功）
        WebinterfaceLogDO webinterfaceLogDO = new WebinterfaceLogDO();
        webinterfaceLogDO.setInterfaceSystemName("微信公众号");
        webinterfaceLogDO.setInterfaceName("获取用户列表");
        webinterfaceLogDO.setInterfaceUrl(userListUrl + "&next_openid=" + next_openid);
        webinterfaceLogDO.setInterfaceRequestMethod("GET");
        webinterfaceLogDO.setInterfaceParam(null);
        webinterfaceLogDO.setInterfaceStatus("成功");
        webinterfaceLogMapper.insert(webinterfaceLogDO);

        try {
            String result = HttpUtils.get(userListUrl + "&next_openid=" + next_openid, new HashMap<>());

            // 解析接口结果
            JSONObject resultJo = JSONObject.parseObject(result);
            Integer errcode = resultJo.getInteger("errcode");
            if (ObjectUtils.isNotEmpty(errcode)) {
                webinterfaceLogDO.setInterfaceStatus("失败");
                webinterfaceLogDO.setInterfaceErrorInfo(result);
                webinterfaceLogMapper.updateById(webinterfaceLogDO);
                return;
            }
            webinterfaceLogDO.setInterfaceErrorInfo(result);
            webinterfaceLogMapper.updateById(webinterfaceLogDO);

            JSONObject dataJo = resultJo.getJSONObject("data");
            JSONArray openidJa = dataJo.getJSONArray("openid");
            int total = resultJo.getIntValue("total");
            int size = (total + 10000 - 1) / 10000;

            // 处理人员信息
            handleData(openidJa, configJo);

            // 根据接口是否返回next_openid，判断是否继续调用接口
            next_openid = resultJo.getString("next_openid");
            for (int i = 1; i < size; i++) {
                result = HttpUtils.get(userListUrl + "&next_openid=" + next_openid, new HashMap<>());

                // 解析接口结果
                resultJo = JSONObject.parseObject(result);
                errcode = resultJo.getInteger("errcode");
                if (ObjectUtils.isNotEmpty(errcode)) {
                    webinterfaceLogDO.setInterfaceStatus("失败");
                    webinterfaceLogDO.setInterfaceErrorInfo(result);
                    webinterfaceLogMapper.updateById(webinterfaceLogDO);
                    break;
                }

                dataJo = resultJo.getJSONObject("data");
                openidJa = dataJo.getJSONArray("openid");
                next_openid = resultJo.getString("next_openid");
                // 处理人员信息
                handleData(openidJa, configJo);
            }
        } catch (Exception e) {
            webinterfaceLogDO.setInterfaceStatus("失败");
            webinterfaceLogDO.setInterfaceErrorInfo(e.getMessage());
            webinterfaceLogMapper.updateById(webinterfaceLogDO);
            logger.error("微信公众号【获取用户列表】接口调用失败！", e);
        }
    }

    /**
     * <p>作者: 张恒
     * <p>描述: 处理人员信息
     * <p>日期: 2025/6/17 14:55
     * @Param openidJa openid列表
     * @Param configJo 配置信息
     */
    private void handleData(JSONArray openidJa, JSONObject configJo) {
        for (int i = 0; i < openidJa.size(); i++) {
            // 获取微信token
            String weixinToken = appTokenService.getWeixinToken();
            if (StringUtils.isEmpty(weixinToken)) {
                throw exception(WEIXIN_TOKEN_NOT_EXISTS);
            }
            String openid = openidJa.getString(i);
            String userInfoUrl = configJo.getString("userInfoUrl");
            userInfoUrl = userInfoUrl + "?access_token="+ weixinToken +"&openid="+ openid +"&lang=zh_CN";

            String result = HttpUtils.get(userInfoUrl, new HashMap<>());
            // 解析接口结果
            JSONObject resultJo = JSONObject.parseObject(result);
            Integer errcode = resultJo.getInteger("errcode");
            if (ObjectUtils.isNotEmpty(errcode)) {
                logger.error("同步微信用户【"+ openid +"】信息失败，失败消息为：" + result);
                throw exception(WEIXIN_USER_SYNC_ERROR, result);
            }

            WeixinUserDO weixinUserDO = BeanUtils.toBean(resultJo, WeixinUserDO.class);
            // 查询本地库中是否有数据
            LambdaQueryWrapper<WeixinUserDO> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(WeixinUserDO::getOpenid, openid);
            List<WeixinUserDO> weixinUserDOS = weixinUserMapper.selectList(queryWrapper);
            if (CollectionUtils.isNotEmpty(weixinUserDOS)) {
                weixinUserDO.setId(weixinUserDOS.get(0).getId());
            }

            weixinUserMapper.insertOrUpdate(weixinUserDO);
        }
    }

}